Public Class rcfNWN2TabletControl
    Private bUpdating As Boolean
    Public bDirty As Boolean = True
    Public pens(2) As PenData
    Public curPen As PenData
    Public srchPen As PenData
    Public penList As List(Of PenData)

    Public Const PEN_NIB = 0
    Public Const PEN_ERASER = 1

    Public TE As NWN2Toolset.NWN2.Views.NWN2TerrainEditorForm

    Const SLOPE = 99 / 39
    Const B = -1.53

    Private Function IsValidRange(ByVal range As String) As Boolean
        Dim check As Integer

        Try
            check = Integer.Parse(range)
        Catch ex As Exception
            Return False
        End Try

        Return True

    End Function


    Private Sub chkBindSize_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkBindSize.CheckedChanged
        If chkBindSize.Checked Then
            txtSize.Enabled = False
            barSize.Enabled = False
        Else
            txtSize.Enabled = True
            barSize.Enabled = True
            'bDirty = True
        End If

        curPen.BoundToSize = chkBindSize.Checked
    End Sub


    Private Sub chkOuter_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkOuter.CheckedChanged
        If chkOuter.Checked Then
            txtOuter.Enabled = False
            barOuter.Enabled = False
        Else
            txtOuter.Enabled = True
            barOuter.Enabled = True
            'bDirty = True
        End If

        curPen.BoundToOuter = chkOuter.Checked
    End Sub

    Private Sub chkPressure_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkPressure.CheckedChanged
        If chkPressure.Checked Then
            txtPressure.Enabled = False
            barPressure.Enabled = False
        Else
            txtPressure.Enabled = True
            barPressure.Enabled = True
            'bDirty = True
        End If

        curPen.BoundToPressure = chkPressure.Checked
    End Sub



    Private Sub barSize_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles barSize.ValueChanged
        If Not bUpdating Then
            bUpdating = True
            txtSize.Text = barSize.Value.ToString
            curPen.Size = barSize.Value * 39.0 / 99.0 + 0.61
            'bDirty = True
            bUpdating = False
        End If
    End Sub

    Private Sub barOuter_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles barOuter.ValueChanged
        If Not bUpdating Then
            bUpdating = True
            txtOuter.Text = barOuter.Value.ToString
            curPen.Outer = barOuter.Value * 39.0 / 99.0 + 0.61
            'bDirty = True
            bUpdating = False
        End If
    End Sub

    Private Sub txtSize_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSize.TextChanged
        If Not bUpdating Then
            bUpdating = True
            If IsValidRange(txtSize.Text) Then
                barSize.Value = Integer.Parse(txtSize.Text)
                curPen.Size = barSize.Value * 39.0 / 99.0 + 0.61
                'bDirty = True
            End If
            bUpdating = False
        End If
    End Sub

    Private Sub barPressure_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles barPressure.ValueChanged
        If Not bUpdating Then
            bUpdating = True
            txtPressure.Text = Math.Round(barPressure.Value / 100.0).ToString
            curPen.Pressure = barPressure.Value
            'bDirty = True
            bUpdating = False
        End If
    End Sub


    Private Sub tabTerrainAdv_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tabAdvanced.Click


    End Sub


    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        'init list
        penList = New List(Of PenData)
        Dim temp As PenData
        'create default pens for now.  Eventuly load from XML file
        temp = New PenData
        temp.Name = "Default Nib (Nib)"
        pens(0) = temp
        penList.Add(temp)
        temp = New PenData
        temp.Name = "Default Eraser (Eraser)"
        pens(1) = temp
        penList.Add(temp)


        'shortcut so I don't have to type it out
        TE = NWN2Toolset.NWN2ToolsetMainForm.App.TerrainEditor

    End Sub

    Private Sub rcfNWN2TabletControl_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        curPen = pens(PEN_NIB)
        UpdateControl()
    End Sub

    Private Sub UpdateControl()
        Dim si As Integer

        bUpdating = True
        If curPen.BoundToSize = True Then
            Me.chkBindSize.Checked = True
        Else
            Me.chkBindSize.Checked = False
        End If

        If curPen.BoundToPressure = True Then
            Me.chkPressure.Checked = True
        Else
            Me.chkPressure.Checked = False
        End If

        If curPen.BoundToOuter = True Then
            Me.chkOuter.Checked = True
        Else
            Me.chkOuter.Checked = False
        End If

        listOps.SetSelected(curPen.Operation, True)

        txtSize.Text = CType(CType(curPen.Size, Single) * 99 / 39 - 1.53, Integer).ToString
        txtOuter.Text = CType(CType(curPen.Outer, Single) * 100 / 40, Integer).ToString
        txtPressure.Text = Math.Round(curPen.Pressure / 100.0).ToString
        barSize.Value = Integer.Parse(txtSize.Text)
        barOuter.Value = Integer.Parse(txtOuter.Text)
        barPressure.Value = curPen.Pressure

        txtMinSize.Text = curPen.MinSize.ToString
        txtMaxSize.Text = curPen.MaxSize.ToString
        txtMinOuter.Text = curPen.MinOuter.ToString
        txtMaxOuter.Text = curPen.MaxOuter.ToString
        txtMinPressure.Text = curPen.MinPressure.ToString
        txtMaxPressure.Text = curPen.MaxPressure.ToString

        Me.barSensitivity.Value = curPen.Sensitivity * 100

        'grass and texture
        lblTexture.Text = curPen.Texture
        lblGrass.Text = curPen.GrassTexture
        lblBladeSize.Text = curPen.BladeSize
        lblBladeVar.Text = curPen.BladeVariation

        'update pen list
        si = lstPens.SelectedIndex
        lstPens.Items.Clear()
        For Each srchPen In penList
            lstPens.Items.Add(srchPen.Name)
        Next
        If si > -1 And si < lstPens.Items.Count Then
            lstPens.SetSelected(si, True)
        End If

        bUpdating = False
    End Sub

    Private Sub txtOuter_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtOuter.TextChanged
        If Not bUpdating Then
            bUpdating = True
            If IsValidRange(txtOuter.Text) Then
                barOuter.Value = Integer.Parse(txtOuter.Text)
                curPen.Outer = barOuter.Value * 39.0 / 99.0 + 0.61
                'bDirty = True
            End If
            bUpdating = False
        End If
    End Sub

    Private Sub txtPressure_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPressure.TextChanged
        If Not bUpdating Then
            bUpdating = True
            If IsValidRange(txtPressure.Text) Then
                barPressure.Value = Integer.Parse(txtPressure.Text)
                curPen.Pressure = barPressure.Value * 9999.0 / 99.0 - 100
                'bDirty = True
            End If
            bUpdating = False
        End If
    End Sub

    Private Sub listOps_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listOps.SelectedIndexChanged
        curPen.Operation = listOps.SelectedIndex
        bDirty = True
    End Sub

    Private Sub txtMinSize_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMinSize.TextChanged
        If IsValidRange(txtMinSize.Text) Then
            curPen.MinSize = Integer.Parse(txtMinSize.Text)
        End If
    End Sub

    Private Sub txtMaxSize_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMaxSize.TextChanged
        If IsValidRange(txtMaxSize.Text) Then
            curPen.MaxSize = Integer.Parse(txtMaxSize.Text)
        End If
    End Sub

    Private Sub txtMinOuter_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMinOuter.TextChanged
        If IsValidRange(txtMinOuter.Text) Then
            curPen.MinOuter = Integer.Parse(txtMinOuter.Text)
        End If
    End Sub


    Private Sub txtMaxOuter_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMaxOuter.TextChanged
        If IsValidRange(txtMaxOuter.Text) Then
            curPen.MaxOuter = Integer.Parse(txtMaxOuter.Text)
        End If
    End Sub

    Private Sub txtMinPressure_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMinPressure.TextChanged
        'If IsValidRange(txtMinPressure.Text) Then
        '    curPen.MinPressure = Integer.Parse(txtMinPressure.Text)
        'End If
        Try
            Dim val = Integer.Parse(txtMinPressure.Text)
            curPen.MinPressure = val
        Catch ex As Exception

        End Try
    End Sub

    Private Sub txtMaxPressure_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMaxPressure.TextChanged
        'If IsValidRange(txtMaxPressure.Text) Then
        '    curPen.MaxPressure = Integer.Parse(txtMaxPressure.Text)
        'End If
        Try
            Dim val = Integer.Parse(txtMaxPressure.Text)
            curPen.MaxPressure = val
        Catch ex As Exception

        End Try
    End Sub

    Private Sub barSensitivity_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles barSensitivity.ValueChanged
        If Not curPen Is Nothing Then
            curPen.Sensitivity = CType(barSensitivity.Value, Single) / 100.0
        End If
    End Sub

    'Public Sub UpdateCurPen()
    '    If curPen.Name = "Nib" Then
    '        pens(0) = curPen
    '    ElseIf curPen.Name = "Eraser" Then
    '        pens(1) = curPen
    '    End If
    'End Sub

    Private Sub barPressure_Scroll(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles barPressure.Scroll

    End Sub

  
    Private Sub btnLoadFromToolset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoadFromToolset.Click
        Dim curControl As System.Windows.Forms.Control
        Dim lstBox As System.Windows.Forms.ListBox
        Dim curItem As Object
        Dim val As String

        lstBox = CType(findControl("listBoxTextureNames", TE.Controls), System.Windows.Forms.ListBox)
        lblTexture.Text = lstBox.SelectedItem.ToString
        curPen.Texture = lblTexture.Text

        lstBox = CType(findControl("listBoxGrass", TE.Controls), System.Windows.Forms.ListBox)
        val = ""
        For Each curItem In lstBox.SelectedItems
            val = val + curItem.ToString + ", "
        Next
        val = val.Substring(0, val.Length - 2)
        lblGrass.Text = val
        curPen.GrassTexture = lblGrass.Text

        curControl = findControl("textBoxGrassVariation", TE.Controls)
        lblBladeVar.Text = CType(curControl, System.Windows.Forms.TextBox).Text
        curControl = findControl("trackBarGrassVariation", TE.Controls)
        curPen.BladeVariation = CType(curControl, System.Windows.Forms.TrackBar).Value

        curControl = findControl("textBoxGrassSize", TE.Controls)
        lblBladeSize.Text = CType(curControl, System.Windows.Forms.TextBox).Text
        curControl = findControl("trackBarGrassSize", TE.Controls)
        curPen.BladeSize = CType(curControl, System.Windows.Forms.TrackBar).Value
    End Sub


    Private Function findControl(ByVal name As String, ByRef controls As System.Windows.Forms.Control.ControlCollection) As System.Windows.Forms.Control
        Dim cur, result As System.Windows.Forms.Control

        For Each cur In controls
            If cur.Name = name Then Return cur
            If cur.HasChildren Then
                result = findControl(name, cur.Controls)
                If Not result Is Nothing Then Return result
            End If
        Next
        Return Nothing
    End Function

    Private Sub btnSetToToolset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSetToToolset.Click
        Dim curControl As System.Windows.Forms.Control
        Dim lstBox As System.Windows.Forms.ListBox
        Dim curItem As Object
        Dim val() As String
        Dim index, i As Integer

        lstBox = CType(findControl("listBoxTextureNames", TE.Controls), System.Windows.Forms.ListBox)
        index = lstBox.FindString(curPen.Texture)
        lstBox.SetSelected(index, True)

        lstBox = CType(findControl("listBoxGrass", TE.Controls), System.Windows.Forms.ListBox)
        val = curPen.GrassTexture.Split(",")

        For i = 0 To lstBox.Items.Count - 1 Step 1
            lstBox.SetSelected(i, False)
        Next

        For i = 0 To val.Length - 1 Step 1            
            index = lstBox.FindString(val(i).Trim)
            lstBox.SetSelected(index, True)
        Next

        curControl = findControl("trackBarGrassVariation", TE.Controls)
        CType(curControl, System.Windows.Forms.TrackBar).Value = curPen.BladeVariation

        curControl = findControl("trackBarGrassSize", TE.Controls)
        CType(curControl, System.Windows.Forms.TrackBar).Value = curPen.BladeSize
    End Sub


    Private Sub btnManagePens_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnManagePens.Click
        Dim penManager As New frmManagePens
        frmManagePens.ShowDialog()
    End Sub

    Private Sub btnCreatePen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreatePen.Click
        Dim temp As New PenData
        Dim count As Integer
        count = 0
        While FindPenName("New Pen" + count.ToString("d2"))
            count += 1
        End While

        temp.Name = "New Pen" + count.ToString("d2")
        penList.Add(temp)
        UpdateControl()
    End Sub

    Private Function FindPenName(ByVal target As String) As Boolean
        Dim result As Boolean
        result = False

        For Each srchPen In penList
            If srchPen.Name = target Then
                result = True
                Exit For
            End If
        Next
        Return result
    End Function

    Private Sub btnDeletePen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeletePen.Click
        Dim target As String

        target = CType(lstPens.SelectedItem, String)
        If target.StartsWith("Default") Then
            System.Windows.Forms.MessageBox.Show("Cannot delete the default pens", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Exit Sub
        End If

        For Each srchPen In penList
            If srchPen.Name = target Then
                penList.Remove(srchPen)
                Exit For
            End If
        Next

        UpdateControl()
    End Sub

    Private Sub btnSetActiveNib_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSetActiveNib.Click
        Dim target As String

        'abort if nothing is selected
        If lstPens.SelectedItem Is Nothing Then
            Exit Sub
        End If
        'abort if the current nib is selected
        If CType(lstPens.SelectedItem, String).EndsWith("(Nib)") Then
            Exit Sub
        End If

        target = CType(lstPens.SelectedItem, String)
        'clear the lstPens display
        lstPens.Items.Clear()

        'cycle through list and change the names
        For Each srchPen In penList
            If srchPen.Name = target Then
                'found our new Nib, so update the name
                srchPen.Name = srchPen.Name + " (Nib)"
                'and update pens                
                pens(PEN_NIB) = srchPen
            ElseIf srchPen.Name.EndsWith("(Nib)") Then
                'found the old nib, so update
                srchPen.Name = srchPen.Name.Substring(0, srchPen.Name.Length - 6)
            End If
            'add the pen back in
            lstPens.Items.Add(srchPen.Name)
        Next

        'refreash the controls
        UpdateControl()

    End Sub

    Private Sub btnSetActiveEraser_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSetActiveEraser.Click
        Dim target As String

        'abort if nothing is selected
        If lstPens.SelectedItem Is Nothing Then
            Exit Sub
        End If
        'abort if the current eraser is selected
        If CType(lstPens.SelectedItem, String).EndsWith("(Eraser)") Then
            Exit Sub
        End If

        target = CType(lstPens.SelectedItem, String)
        'clear the lstPens display
        lstPens.Items.Clear()

        'cycle through list and change the names
        For Each srchPen In penList
            If srchPen.Name = target Then
                'found our new Eraser, so update the name
                srchPen.Name = srchPen.Name + " (Eraser)"
                'and update pens                
                pens(PEN_ERASER) = srchPen
            ElseIf srchPen.Name.EndsWith("(Eraser)") Then
                'found the old Eraser, so update
                srchPen.Name = srchPen.Name.Substring(0, srchPen.Name.Length - 9)
            End If
            'add the pen back in
            lstPens.Items.Add(srchPen.Name)
        Next

        'refreash the controls
        UpdateControl()
    End Sub

    Private Sub lstPens_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstPens.SelectedIndexChanged
        Dim selected As PenData = Nothing
        Dim target As String
        If Not bUpdating Then
            bUpdating = True
            'find the selected pen
            target = lstPens.SelectedItem
            
            For Each srchPen In penList
                If srchPen.Name = target Then
                    selected = srchPen
                    Exit For
                End If
            Next
            If selected Is Nothing Then
                Windows.Forms.MessageBox.Show("Failed to find selected pen in lstPens_SelectedIndexChanged")
                bUpdating = False
                Exit Sub
            End If
            'set curPen to it
            curPen = selected
            bUpdating = False
            'update controls
            UpdateControl()
        End If
        
    End Sub


End Class
